﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Reflection;
using Comm.PublicClass;

namespace WsProtocol.PublicClass
{
    public class PtlPubConsts
    {
        public delegate void EventAfterENCConnect(int iresult);  //连接加密机后的操作委托  
        
        //定义枚举
        //public enum PtlType { Ptl645_07, Ptl69845 };  //协议类别

        public enum TNodeMode {NNode,NData,NFormat,NParameter,NFlag}; //节点类型  节点 数据 格式 参数 数据标识
        public enum TDataType { DTBin, DTBCD, DTHex, DTInt, DTASCII, DTFloat, DTDouble };  //数据类型
        public enum TAnalysisMode { AMByte, AMBit };  //分解方式  按字节? 按位?

        public const string datahead = "<%";  //数据特殊处理起始标志
        public const string dataend = "%>";   //数据特殊处理结束标志
           

        /// <summary>
        /// 数据特殊处理结构
        /// </summary>
        public struct SValueFunc
        {
            public string FuncName;  //特殊处理种类
            public string NodeName;  //针对的节点名 
            public string BackUp1;  //备用
        }

        //无固定长度的格式
        public const string RandomFormat = "..";


        //按字节解析节点结构
        public class TByteFormat
        {
            public TAnalysisMode AnaMode { get; set; } //分解方式
            public bool IfRepeat { get; set; }  //是否可重复
            public TByteFormat ParFormat { get; set; }  //父节点
            public bool IfValid { get; set; }  //是否有效
            public TNodeMode NodeMode { get; set; } //节点类型
            public string ItemData { get; set; } //原始数据
            public string ItemValue { get; set; }   //分解后的值 或 设定值
            public string ItemName { get; set; }   //数据域名称
            public string ItemFormat { get; set; } //数据域格式
            public int ItemPoint { get; set; }  //小数位数
            public string ItemDisplay { get; set; } //分解描述        
            public string ItemUnit { get; set; }   //单位
            public string ItemParform { get; set; } //参数窗口类型
            public TDataType ItemDatatype { get; set; }     //数据类型 1:BCD 2:ASCII 3:十进制  4:二进制
            public int ItemByteChange { get; set; }   //是否低字节在前  1:是  0:否
            public int ItemBitChange { get; set; }   //是否低位在前  1:是  0:否
            public int IfShow { get; set; }     //是否显示  1:是  0:否
            public string SendFunc { get; set; }  //发送处理
            public string RecFunc { get; set; }  //接收处理
            public List<TByteFormat> EleLst { get; set; } //下级节点格式

            public TByteFormat()
            {
                AnaMode = TAnalysisMode.AMByte;  //分解方式
                IfValid = true;  //是否有效
                NodeMode = TNodeMode.NData;  //节点类型
                ItemData = "";  //原始数据
                ItemValue = "";   //分解后的值 或 设定值
                ItemName = "";   //数据域名称
                ItemFormat = ""; //数据域格式
                ItemDisplay = ""; //分解描述        
                ItemUnit = "";    //单位
                ItemParform = ""; //参数窗口类型
                ItemDatatype = TDataType.DTBCD;     //数据类型 1:BCD 2:ASCII 3:十进制  4:二进制
                ItemByteChange = 1;   //是否低字节在前  1:是  0:否
                ItemBitChange = 1;   //是否低位在前  1:是  0:否
                IfShow = 1;     //是否显示  1:是  0:否
                SendFunc = "";  //发送处理脚本
                RecFunc = "";  //接收处理脚本

                EleLst = new List<TByteFormat>(); //下级节点格式
            }

            //增加格式
            public void AddFormat(TByteFormat newformat)
            {
        	    newformat.ParFormat = this;
        	    EleLst.Add(newformat);
            }
            
            //删除格式
            public void RemoveFormat(TByteFormat newformat)
            {
                for (int i = EleLst.Count - 1; i >= 0; i--)
        	    {
                    if (EleLst[i] == newformat)
                        EleLst.Remove(EleLst[i]);
        	    }
            }
            
            //清空格式
            public void ClearFormat()
            {
                EleLst.Clear();
            }
            
            //克隆当前格式
            public TByteFormat Copy() 
            {
                //新建一个
                TByteFormat newattr = new TByteFormat();

                //复制属性
                PropertyInfo[] fromFields = typeof(TByteFormat).GetProperties();
                PubFunction.SetProperties(fromFields, this, newattr);

                //复制子节点
                newattr.EleLst = new List<TByteFormat>();
                if (this.EleLst != null)
                    for (int i = 0; i < this.EleLst.Count; i++)
                    {
                        TByteFormat sonAttr = this.EleLst[i].Copy();
                        sonAttr.ParFormat = newattr;
                        newattr.EleLst.Add(sonAttr);
                    }

                return newattr;
            }  

            //克隆下级节点格式中所有可复制的
            public int CloneFormat()
            {
        	    int copynodecount = 0;  //复制的节点个数
                for (int i = 0; i < EleLst.Count; i++)
                {
                    TByteFormat xe = EleLst[i];
            	    if (!xe.IfRepeat)
                        continue;
                    copynodecount++;
                    TByteFormat newson = (TByteFormat) xe.Copy();
                    newson.ItemName = newson.AddNOOnce(newson.ItemName, -1, 1, true);  //名称中的序号+1

                    newson.ItemData = "";
                    newson.ItemValue = "";
                    
                    
                    EleLst.Add(newson);

                    xe.IfRepeat = false; //将原来的可重复节点置为不可重复，重复节点由复制出的新节点代替

                }
                return copynodecount;
            	
            }
            
            
            //
            /// <summary>
            /// 增加计数  只增加里面的其中一个累加值
            /// </summary>
            /// <param name="pstr">原始字符串</param>
            /// <param name="ino">指定计数 -1表示无效</param>
            /// <param name="appendno">在当前计数基础上的增加值</param>
            /// <param name="front">true表示从前面找   false表示从后面找</param>
            /// <returns></returns>
            public string AddNOOnce(string pstr, int ino, int appendno, bool front)
            {
                string resultstr = pstr;
                if (front)
                {
                    int Fpos = pstr.IndexOf('[');
                    int Lpos = pstr.IndexOf(']');
                    string otherstr = "";
                    if (Fpos >= 0 && Lpos >= 0)
                    {
                        if (Fpos > 0)
                            otherstr = pstr.Substring(0, Fpos - 1);

                        int No = ino;
                        if (No < 0)
                        {
                            string nostr = pstr.Substring(Fpos + 1, Lpos - 1);
                            No = Convert.ToInt16(nostr);
                            No += appendno;
                        }

                        resultstr = '['
                                  + Convert.ToString(No)
                                  + ']'
                                  + pstr.Substring(Lpos + 1);
                    }
                    //if (otherstr.IndexOf('[') >= 0 && otherstr.IndexOf(']') >= 0)
                    //    otherstr = AddNO(otherstr);
                    resultstr = otherstr + resultstr;
                }
                else
                {
                    int Fpos = pstr.LastIndexOf('[');
                    int Lpos = pstr.LastIndexOf(']');
                    string otherstr = "";
                    if (Fpos >= 0 && Lpos >= 0)
                    {
                        if (Fpos > 0)
                            otherstr = pstr.Substring(0, Fpos - 1);
                        int No = ino;
                        if (No < 0)
                        {
                            string nostr = pstr.Substring(Fpos + 1, Lpos - 1);
                            No = Convert.ToInt16(nostr);
                            No += appendno;
                        }
                        resultstr = '['
                                  + Convert.ToString(No)
                                  + ']'
                                  + pstr.Substring(Lpos + 1);
                    }
                    //if (otherstr.LastIndexOf('[') >= 0 && otherstr.LastIndexOf(']') >= 0)
                    //    otherstr = AddNO(otherstr);
                    resultstr = otherstr + resultstr;
                }
                return resultstr;
            }


            //增加计数
            public static string AddNO(string pstr)
            {
                string resultstr = pstr;
                int Fpos = pstr.LastIndexOf('[');
                int Lpos = pstr.LastIndexOf(']');
                string otherstr = string.Empty;
                if (Fpos >= 0 && Lpos >= 0)
                {
                    if (Fpos > 0)
                        otherstr = pstr.Substring(0, Fpos);

                    string nostr = pstr.Substring(Fpos + 1, Lpos - Fpos - 1);
                    int No = Convert.ToInt32(nostr);
                    No += 1;
                    resultstr = '['
                              + No.ToString()
                              + ']'
                              + pstr.Substring(Lpos + 1);
                }
                if (otherstr.LastIndexOf('[') >= 0 && otherstr.LastIndexOf(']') >= 0)
                    otherstr = AddNO(otherstr);
                resultstr = otherstr + resultstr;
                return resultstr;
            }


            //增加计数  指定数值
            public static string AddNO(string pstr, int ino)
            {
                string resultstr = pstr;
                int Fpos = pstr.LastIndexOf('[');
                int Lpos = pstr.LastIndexOf(']');
                string otherstr = string.Empty;
                if (Fpos >= 0 && Lpos >= 0)
                {
                    if (Fpos > 0)
                        otherstr = pstr.Substring(0, Fpos);

                    resultstr = '['
                              + ino.ToString()
                              + ']'
                              + pstr.Substring(Lpos + 1);
                }
                resultstr = otherstr + resultstr;
                return resultstr;
            }
        }
    }
}